package com.xiaode.controller.app.chat;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.jfinal.aop.Before;
import com.jfinal.kit.Kv;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import com.xiaode.common.constant.Const;
import com.xiaode.common.model.*;
import com.xiaode.common.model.dto.chatGroup.DepartmentDTO;
import com.xiaode.exce.EnumError;
import com.xiaode.util.ChatUtil;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class ChatGroupMannageService {
	
	/**
	 * 修改群聊信息
	 */
    public Ret updateChatGroupData(Integer accountIdMy, Integer chatGroupId, String name, String notice) throws Exception {
        ChatGroupUser chatGroupUser = ChatGroupUser.dao.findFirst("SELECT * FROM chat_group_user WHERE chatGroupId = ? AND accountId = ?", chatGroupId, accountIdMy);
        if (BeanUtil.isEmpty(chatGroupUser)) {
            return Ret.fail().set("error", EnumError.NOT_IN_GROUP.getObj());
        }
        if (chatGroupUser.getLevel() != Const.chatGroupUserLevel.LEADER && chatGroupUser.getLevel() != Const.chatGroupUserLevel.MANAGE) {
            return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
        }
        ChatGroup chatGroup = ChatGroup.dao.findById(chatGroupId);
        if (BeanUtil.isEmpty(chatGroup)) {
            return Ret.fail().set("error", EnumError.GROUP_NOT_EXIT.getObj());
        }
        if (name != null) {
            chatGroup.setName(name);
        }
        if (notice != null) {
            chatGroup.setNotice(notice);
        }
        chatGroup.setVersion(chatGroup.getVersion() + 1);
        chatGroup.update();

        return Ret.ok();
    }

    /**
     * 更换群主
     */
    @Before(Tx.class)
    public Ret updateGroupLeader(Integer accountId, Integer accountIdMy, Integer chatGroupId) throws Exception {
    	//判断我是不是这个群的群主
    	ChatGroup chatGroup = ChatGroup.dao.findFirst("SELECT * FROM chat_group WHERE id = ? AND leaderAccountId = ?", chatGroupId, accountIdMy);
    	if(BeanUtil.isEmpty(chatGroup)) {
    		return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
    	}
    	//判断对方是不是群成员
    	ChatGroupUser chatGroupUser = ChatGroupUser.dao.findFirst("SELECT * FROM chat_group_user WHERE chatGroupId = ? AND accountId = ? ", chatGroupId, accountId);       
    	if (BeanUtil.isEmpty(chatGroupUser)) {
            return Ret.fail().set("error", EnumError.HE_NOT_IN_GROUP.getObj());
        }
    	//更新自己为普通群成员
    	Db.update("UPDATE chat_group_user SET level = ? WHERE chatGroupId = ? AND accountId = ? ", Const.chatGroupUserLevel.COMMON, chatGroupId, accountIdMy);
        //更新对方
        chatGroupUser.setLevel(Const.chatGroupUserLevel.LEADER);
        chatGroupUser.update();
        //跟新群
        chatGroup.setLeaderAccountId(accountId);
        chatGroup.setVersion(chatGroup.getVersion() + 1);
        chatGroup.update();
        //如有禁言
        if (chatGroup.getIsEstoppel()) {
            //解除新群主禁言  
            ChatUtil.relieveEstoppelByGroup(chatGroupId, Arrays.asList(accountId));
            //给自己添加禁言
            ChatUtil.estoppelByGroup(chatGroupId, Arrays.asList(accountIdMy));
        }
        return Ret.ok();
    }

    /**
     * 添加/删除群管理
     */
    public Ret updateGroupManage(Integer chatGroupId, Integer accountIdMy, Integer accountId, Boolean flag) throws Exception {
    	
    	ChatGroup chatGroup = ChatGroup.dao.findFirst("SELECT * FROM chat_group WHERE id = ? AND leaderAccountId = ?", chatGroupId, accountIdMy);
    	if (BeanUtil.isEmpty(chatGroup)) {
            return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
        }
        ChatGroupUser chatGroupUser = ChatGroupUser.dao.findFirst("SELECT * FROM chat_group_user WHERE chatGroupId = ? AND accountId = ?", chatGroupId, accountId);       
        if (BeanUtil.isEmpty(chatGroupUser)) {
            return Ret.fail().set("error", EnumError.NOT_IN_GROUP.getObj());
        }
        if (flag) {
        	chatGroupUser.setLevel(2);
        } else {
        	chatGroupUser.setLevel(1);
        }
        chatGroupUser.update();
        // 增加群版本
        chatGroup.setVersion(chatGroup.getVersion() + 1);
        chatGroup.update();
        //解除/添加用户禁言
        if (chatGroup.getIsEstoppel()) {
        	ArrayList<Integer> list = new ArrayList<Integer>();
        	list.add(accountId);
            if (flag) {
            	ChatUtil.relieveEstoppelByGroup(chatGroupId, list);
            } else {
                ChatUtil.estoppelByGroup(chatGroupId, list);
            }
        }
        
        return Ret.ok();
    }

    /**
     * 全体禁言
     */
    public Ret muteAll(Integer accountIdMy, Integer chatGroupId, Boolean flag) throws Exception {
        
        //判断我是否有权限
        ChatGroupUser chatGroupUser = ChatGroupUser.dao.findFirst("SELECT * FROM chat_group_user WHERE chatGroupId = ? AND accountId = ?", chatGroupId, accountIdMy);
        if (BeanUtil.isEmpty(chatGroupUser)) {
            return Ret.fail().set("error", EnumError.NOT_IN_GROUP.getObj());
        }
        if (chatGroupUser.getLevel() != Const.chatGroupUserLevel.LEADER && chatGroupUser.getLevel() != Const.chatGroupUserLevel.MANAGE) {
            return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
        }
        //禁言
        List<Integer> accountIdList = Db.query("SELECT accountId FROM chat_group_user WHERE chatGroupId = ? AND level = ?", chatGroupId, Const.chatGroupUserLevel.COMMON);
        //跟新群
        ChatGroup chatGroup = ChatGroup.dao.findById(chatGroupId);
        chatGroup.setIsEstoppel(flag);
        chatGroup.update();
        //发送禁言消息
        if (flag) {
            ChatUtil.estoppelByGroup(chatGroupId, accountIdList);
        } else {
            ChatUtil.relieveEstoppelByGroup(chatGroupId, accountIdList);
        }
        
        return Ret.ok();
    }

    /**
     * 消息免打扰
     */
    public Ret disturb(Integer accountId, Integer chatGroupId, Integer flag) throws Exception {
    	ChatGroupUser chatGroupUser = ChatGroupUser.dao.findFirst("SELECT * FROM chat_group_user WHERE chatGroupId = ? AND accountId = ?", chatGroupId, accountId);
        if (BeanUtil.isEmpty(chatGroupUser)) {
            return Ret.fail().set("error", EnumError.NOT_IN_GROUP.getObj());
        }
        chatGroupUser.setDisturb(flag);
        chatGroupUser.update();
        
        return Ret.ok();
    }

    /**
     * 查询当前用户群身份
     */
    public Ret getGroupUserIdentity(Integer accountIdMy, Integer chatGroupId) throws Exception {
    	Integer level = Db.queryInt("SELECT level FROM chat_group_user WHERE chatGroupId = ? AND accountId = ?", chatGroupId, accountIdMy); 	
        if (BeanUtil.isEmpty(level)) {
            return Ret.fail().set("error", EnumError.NOT_IN_GROUP.getObj());
        }
        return Ret.ok("level", level);
    }
    
    /**
     * 查询当前用户群的公告
     */
    public Ret getGroupNotice(Integer accountIdMy, Integer chatGroupId) throws Exception {
    	Integer id = Db.queryInt("SELECT id FROM chat_group_user WHERE chatGroupId = ? AND accountId = ?", chatGroupId, accountIdMy);
        if (BeanUtil.isEmpty(id)) {
            return Ret.fail().set("error", EnumError.NOT_IN_GROUP.getObj());
        }
        String notice = Db.queryStr("SELECT notice FROM chat_group WHERE id = ?", chatGroupId);
        return Ret.ok("notice", notice);
    }

    /**
     * 添加群成员
     */
    public Ret addMembers(Integer chatGroupId, String accountIds) throws Exception {
        
        ChatGroup chatGroup = ChatGroup.dao.findById(chatGroupId);
        if (BeanUtil.isEmpty(chatGroup)) {
            return Ret.fail().set("error", EnumError.GROUP_NOT_EXIT.getObj());
        }
        //存放前端所有要添加的用户账号
        List<Integer> accountIdList = JSONUtil.toList(accountIds, Integer.class);
        //存放真正要添加的用户账号
        List<Integer> addAccountIdList = new ArrayList<Integer>();
        //存放所有要入库的新增成员
        List<ChatGroupUser> addGroupUserList = new ArrayList<ChatGroupUser>();
        //获取群中原有的用户账号
        List<Integer> originalAccountIdList = Db.query("SELECT accountId FROM chat_group_user WHERE chatGroupId = ?", chatGroupId);
        //过滤已有的，并建实体类
        for(Integer accountId : accountIdList) {
        	if(!originalAccountIdList.contains(accountId)) {
        		
        		Record accountInfo = Redis.use().hget(Const.user.AccountIdInfo, accountId);
        		ChatGroupUser chatGroupUser = new ChatGroupUser();
                chatGroupUser.setUserType(accountInfo.getInt("userType"));
                chatGroupUser.setAccountId(accountId);
                chatGroupUser.setChatGroupId(chatGroupId);
                chatGroupUser.setLevel(Const.chatGroupUserLevel.COMMON);
                addGroupUserList.add(chatGroupUser);
                
                addAccountIdList.add(accountId);
        	}
        }
        //判断群的最大成员数量
        if (originalAccountIdList.size() + addGroupUserList.size() > chatGroup.getMemberNum()) {
            return Ret.fail().set("error", EnumError.GROUP_MEMBER_NUM_MAX.getObj());
        }
        //添加群聊
        if (addGroupUserList.size() > 0) {
            //给群聊增加版本
            chatGroup.setVersion(chatGroup.getVersion() + 1);
            chatGroup.update();
            Db.batchSave(addGroupUserList, addGroupUserList.size());
            //发送群聊消息
            ChatUtil.addGroupsByGroupId(chatGroupId, addAccountIdList);
        }
        
        return Ret.ok();
    }

    /**
     * 踢出群成员
     */
    public Ret kickOutChatGroup(Integer chatGroupId, String accountIds, Integer accountIdMy){
    	//判断是否有踢人权限
        ChatGroup chatGroup = ChatGroup.dao.findFirst("SELECT * FROM chat_group WHERE id = ? AND leaderAccountId = ?", chatGroupId, accountIdMy);
        if(BeanUtil.isEmpty(chatGroup)) {
        	return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
        }
        List<Integer> deleteAccountIdList = JSONUtil.toList(accountIds, Integer.class);
    	//去除自己和群主
    	deleteAccountIdList.remove(chatGroup.getLeaderAccountId());
    	deleteAccountIdList.remove(accountIdMy);
    	if(deleteAccountIdList.size() > 0) {
    		Db.template("delChatGroupUser", Kv.of("accountIdList", deleteAccountIdList).set("chatGroupId", chatGroup.getId())).delete();
        	//发送群聊消息
            ChatUtil.deleGroupsByGroupId(chatGroupId, deleteAccountIdList);
    	}
    	return Ret.ok();
    }
    
    /**
     * 校验群聊版本
     */
    public Ret checkGrooupVersion(Integer userId, Integer userType, Integer groupId, Integer version) throws Exception {
        ChatGroup group = ChatGroup.dao.findById(groupId);
        if (BeanUtil.isEmpty(group)) {
            return Ret.fail().set("error", EnumError.GROUP_NOT_EXIT.getObj());
        }
        ChatGroupUser first = ChatGroupUser.dao.findFirst("SELECT id FROM chat_group_user WHERE userId = ? AND userType = ? AND chatGroupId = ?", userId, userType, groupId);
        if (first == null) {
            return Ret.fail().set("error", EnumError.NOT_IN_GROUP.getObj());
        }
        int ver = group.getVersion();
        if (ver != version) {
            Kv kv = Kv.by("groupId", groupId);
            List<Record> records = Db.template("findStuMemberByGroupId", kv).find();
            List<Record> teaRecords = Db.template("findTeaMemberByGroupId", kv).find();
            List<Record> parRecords = Db.template("findParMemberByGroupId", kv).find();
            records.addAll(teaRecords);
            records.addAll(parRecords);
            Collections.sort(records, (o1, o2) -> {
                if (o1.getInt("level") == 0) {
                    return -1;
                }
                if (o2.getInt("level") == 0) {
                    return 1;
                }
                return -(o1.getInt("level") - o2.getInt("level"));
            });
            return Ret.ok("members", records).set("chatGroup", group).set("needUpdate", true);
        }
        return Ret.ok("members", null).set("chatGroup", null).set("needUpdate", false);
    }

    /**
     * 创建群聊
     */
    @Before(Tx.class)
    public Ret createChatGroup(Integer accountIdMy, Integer userType, String accountIds, String chatGroupIds, String departmentIds) throws Exception {

    	if (userType != Const.UserType.admin) {
            return Ret.fail().set("error", EnumError.STUDENT_NOT_ALLOW_CREATE_GROUP.getObj());
        }
    	Record accountInfoMy = Redis.use().hget(Const.user.AccountIdInfo, accountIdMy);
    	//先创建群
    	ChatGroup chatGroup = new ChatGroup();
        chatGroup.setVersion(1);
        chatGroup.setType(Const.chatService.COMMON_GROUP);
        chatGroup.setLeaderAccountId(accountIdMy);
        chatGroup.setIsEstoppel(false);
        chatGroup.setName(accountInfoMy.getStr("name"));
        chatGroup.setCode(System.currentTimeMillis() + "" + accountIdMy);
        chatGroup.setIsEstoppel(false);
        chatGroup.setMemberNum(200);
        chatGroup.setNeedRead(2);
        chatGroup.save();
        
        //存放真正要添加的用户账号
        Set<Integer> addAccountIdSet = new HashSet<Integer>();
        //存放所有要入库的新增成员
        List<ChatGroupUser> addGroupUserList = new ArrayList<ChatGroupUser>();
        //添加账号
        addAccountIdSet.add(accountIdMy);
        List<Integer> accountList = JSONUtil.toList(accountIds, Integer.class);
        addAccountIdSet.addAll(accountList);
        //添加群
        List<Integer> chatGroupIdList = JSONUtil.toList(chatGroupIds, Integer.class);
        if(chatGroupIdList.size() > 0 ) {
        	List<Integer> groupAccountList = Db.template("findAccountByGroupIds", Kv.of("chatGroupList", chatGroupIdList)).query();
        	addAccountIdSet.addAll(groupAccountList);
        }
        //组织架构
        List<DepartmentDTO> departmentList = JSONUtil.toList(departmentIds, DepartmentDTO.class);
        //解析部门及其子部门,区分部门下的admin 与 student 添加到不同的集合中
        if (ObjectUtil.isAllNotEmpty(departmentList)) {
            HashMap<Integer, Set<Integer>> hashMap = new HashMap<>();
            departmentList.stream().forEach(departmentDTO -> {
                Integer stratum = departmentDTO.getStratum();
                Set<Integer> set = hashMap.get(stratum);
                if (set == null) {
                    HashSet<Integer> hashSet = new HashSet<>();
                    hashSet.add(departmentDTO.getId());
                    hashMap.put(stratum, hashSet);
                } else {
                    set.add(departmentDTO.getId());
                }
            });
            // 架构
            for (int i = 1; i < 4; i++) {
                Set<Integer> integers = hashMap.get(i);
                if (ObjectUtil.isAllNotEmpty(integers)) {
                    Kv kv = Kv.by("stratumIdList", integers).set("stratum", i);
                    List<Record> recordList = Db.template("findAdminByStatum", kv).find();
                    recordList.stream().forEach(record -> addAccountIdSet.add(record.getInt("accountId")));
                    if (i == 1) {
                        Set<Integer> integerSet = hashMap.get(2);
                        List<OrgGrade> orgGrades = OrgGrade.dao.find("SELECT id FROM org_grade WHERE isRoot = 0");
                        if (integerSet == null) {
                            integerSet = new HashSet<Integer>();
                            hashMap.put(2, integerSet);
                        }
                        integerSet = hashMap.get(2);
                        if (!orgGrades.isEmpty()) {
                            for (OrgGrade orgGrade : orgGrades) {
                                integerSet.add(orgGrade.getId());
                            }
                        }
                    }
                    if (i == 2) {
                        Set<Integer> integerSet = hashMap.get(3);
                        Kv kv1 = Kv.by("gradeIdList", integers);
                        List<Record> orgClasses = Db.template("findOrgClassByGradeId", kv1).find();
                        if (integerSet == null) {
                            integerSet = new HashSet<Integer>();
                            hashMap.put(3, integerSet);
                        }
                        integerSet = hashMap.get(3);
                        if (!orgClasses.isEmpty()) {
                            for (Record orgClass : orgClasses) {
                                integerSet.add(orgClass.getInt("id"));
                            }
                        }
                    }
                }
            }
            Set<Integer> clasIds = hashMap.get(3);
            //添加学生
            if (clasIds != null && clasIds.size() > 0) {
                Kv kv = Kv.by("classIds", clasIds);
                List<Record> recordList = Db.template("findStudentByClassIds", kv).find();
                recordList.stream().forEach(record -> addAccountIdSet.add(record.getInt("accountId")));
            }
        }
        
        //群成员数量不能超过100
        if (addAccountIdSet.size() > chatGroup.getMemberNum()) {
            Ret.fail().set("error", EnumError.GROUP_MEMBER_NUM_MAX.getObj());
        }
        for(Integer addAccountId : addAccountIdSet) {
        	Record accountInfo = Redis.use().hget(Const.user.AccountIdInfo, addAccountId);
    		ChatGroupUser groupUser = new ChatGroupUser();
            groupUser.setLevel(Const.chatGroupUserLevel.COMMON);
            groupUser.setAccountId(addAccountId);
            groupUser.setUserType(accountInfo.getInt("userType"));
            groupUser.setChatGroupId(chatGroup.getId());
            if(addAccountId == accountIdMy) {
            	groupUser.setLevel(Const.chatGroupUserLevel.LEADER);
            }
            addGroupUserList.add(groupUser);
        }
        
        //给学生与教师添加版本
        Db.batchSave(addGroupUserList, addGroupUserList.size());
        ChatUtil.addGroupsByGroupId(chatGroup.getId(), new ArrayList<Integer>(addAccountIdSet));
        
        return Ret.ok("groupId", chatGroup.getId());
    }

    /**
     * 解散群聊
     */
    public Ret delChatGroup(Integer accountIdMy, Integer chatGroupId) throws Exception {
    	ChatGroupUser chatGroupUser = ChatGroupUser.dao.findFirst("SELECT * FROM chat_group_user WHERE chatGroupId = ? AND accountId = ? AND level = ?", chatGroupId, accountIdMy, Const.chatGroupUserLevel.LEADER);
        if (BeanUtil.isEmpty(chatGroupUser)) {
            return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
        }
        List<Integer> accountIdList = Db.query("SELECT accountId FROM chat_group_user WHERE chatGroupId = ?", chatGroupId);
        //删除群聊
        Db.deleteById("chat_group", chatGroupId);
        Db.delete("DELETE FROM chat_group_user WHERE chatGroupId = ?", chatGroupId);
        
        ChatUtil.deleGroupsByGroupId(chatGroupId, accountIdList);
    	
        return Ret.ok();
    }

    /**
     * 退出群聊
     */
    public Ret quitChatGroup(Integer accountId, Integer chatGroupId) throws Exception {
    	ChatGroup group = ChatGroup.dao.findById(chatGroupId);
        if (BeanUtil.isEmpty(group)) {
            return Ret.fail().set("error", EnumError.GROUP_NOT_EXIT.getObj());
        }
    	ChatGroupUser chatGroupUser = ChatGroupUser.dao.findFirst("SELECT * FROM chat_group_user WHERE chatGroupId = ? AND accountId = ?", chatGroupId, accountId);
        if (BeanUtil.isEmpty(chatGroupUser)) {
            return Ret.ok();
        }
        chatGroupUser.delete();
        //删除im聊天服务中的用户关系
        ArrayList<Integer> list = new ArrayList<>();
        list.add(chatGroupId);
        ChatUtil.deleGroups(accountId, list);
        group.setVersion(group.getVersion() + 1);
        group.update();
        
        return Ret.ok();
    }

    /**
     * 添加聊天
     * ps:因为不需要好友验证所有没往im中发送好友添加清求
     */
    @Before(Tx.class)
    public Ret addChatSession(Integer accountIdMy, Integer accountId) throws Exception {
        Record accountInfo = Redis.use().hget(Const.user.AccountIdInfo, accountId);
        if(BeanUtil.isEmpty(accountInfo)) {
        	return Ret.fail().set("error", EnumError.USER_NULL.getObj());
        }
        String s = ChatUtil.sessionId(accountIdMy, accountId);
        Friends first = Friends.dao.findFirst("SELECT * FROM friends WHERE conversation = ?", s);
        if (BeanUtil.isEmpty(first)) {
            Friends friends = new Friends();
            friends.setConversation(s);
            friends.setAccountId1(accountId);
            friends.setAccountId2(accountIdMy);
            friends.setFriendsTime(LocalDateTime.now());
            friends.save();
        }
        return Ret.ok();
    }

    /**
     * 查询群聊会话
     */
    public Ret findChatSession(Integer accountId) throws Exception {
    	ArrayList<Record> accountInfoList = new ArrayList<>();
    	List<Integer> friendAccountIdList = Db.query("SELECT accountId2 FROM friends WHERE accountId1 = ? UNION SELECT accountId1 FROM friends WHERE accountId2 = ?", accountId, accountId);
    	for(Integer friendAccountId : friendAccountIdList) {
    		Record accountInfo = Redis.use().hget(Const.user.AccountIdInfo, friendAccountId);
    		accountInfoList.add(accountInfo);
    	}
        List<Record> records = Db.find("SELECT cg.* FROM chat_group_user cgu INNER JOIN chat_group cg ON cg.id = cgu.chatGroupId WHERE cgu.accountId = ?", accountId);
        return Ret.ok("friends", accountInfoList).set("chatGroup", records);
    }

    /**
     * 单方面删除聊天会话
     */
    public Ret delChatSession(Integer accountIdMy, Integer accountId) {
        String s = ChatUtil.sessionId(accountIdMy, accountId);
        Db.delete("DELETE FROM friends WHERE conversation = ?", s);
        return Ret.ok();
    }

    /**
	 * 获取群聊成员
	 */
	public Ret findMembersByGroupId(Integer accountId, Integer groupId) {
		ChatGroupUser first = ChatGroupUser.dao.findFirst("SELECT id FROM chat_group_user WHERE accountId = ? AND chatGroupId = ?", accountId, groupId);
		if (first == null){
			return Ret.fail().set("error",EnumError.NOT_IN_GROUP.getObj());
		}
		Kv kv = Kv.by("groupId", groupId);
		List<Record> records = Db.template("findStuMemberByGroupId", kv).find();
		List<Record> teaRecords = Db.template("findTeaMemberByGroupId", kv).find();
		List<Record> parRecords = Db.template("findParMemberByGroupId", kv).find();
		records.addAll(teaRecords);
		records.addAll(parRecords);
		Collections.sort(records,(o1,o2)->{
			if (o1.getInt("level") ==0){
				return -1;
			}
			if (o2.getInt("level") == 0){
				return 1;
			}
			return -(o1.getInt("level") - o2.getInt("level"));
		});
		ChatGroup chatGroup = ChatGroup.dao.findById(groupId);
		return Ret.ok("members",records).set("chatGroup",chatGroup);
	}
    
    
    
	
	
	
	
	
	
	
	
	
	
    /**
     * 查询年级公告
     */
    public Ret findGradeNotice(Integer userId, Integer userType, Integer page, Integer limit, Integer state) throws Exception {
        Cache redis = Redis.use();
        //获取用户所在年级
        List<Integer> gradeIds = new ArrayList<Integer>();
        if(userType == Const.UserType.student) {//学生
        	Student s = Student.dao.findById(userId);
        	OrgClass clas = OrgClass.dao.findById(s.getClasId());
        	gradeIds.add(clas.getAdminGradeId());
        }
        if(userType == Const.UserType.admin) {//老师
        	List<OrgAdmin> oas = OrgAdmin.dao.find("SELECT * FROM org_admin WHERE adminId = ?",userId);
        	for (OrgAdmin oa : oas) {
        		if (oa.getStratum() == 1) {
        			//TODO 这里可能会改变
        			gradeIds.add(1);
        			gradeIds.add(2);
        			gradeIds.add(5);
				} else if (oa.getStratum() == 2) {
					if (oa.getStratumId() < 4) {
						gradeIds.add(oa.getStratumId());
					}
				} else {
					List<OrgClass> all = OrgClass.dao.find("SELECT * FROM org_class WHERE adminGradeId < 4");
					Map<Integer, Integer> map = all.stream().collect(Collectors.toMap(OrgClass::getId, OrgClass::getAdminGradeId));
					Integer gradeId = map.get(oa.getStratumId());
					if (gradeId != null) {
						gradeIds.add(gradeId);
					}
				}
        	}
        }
        HashMap<Integer, Page<Record>> hashMap = new HashMap<>();
        HashMap<Integer, Integer> map = new HashMap<>();
        Kv kv = Kv.by("userId", userId).set("userType", userType).setIfNotNull("state", state);
        for (Integer gradeId : gradeIds) {
            kv.set("gradeId", gradeId);
            Page<Record> recordPage = Db.template("findGradeNotice", kv).paginate(page, limit);
            List<Record> list = recordPage.getList();
            for (Record record : list) {
                Admin o = redis.get(Const.user.Admin + record.getInt("userId"));
                record.put("userName", o.getName());
            }
            Integer num = Db.queryInt("SELECT COUNT(*) FROM grade_notice_log WHERE userId = ? AND userType = ? AND gradeId = ? AND state = 1", userId, userType, gradeId);
            hashMap.put(gradeId, recordPage);
            map.put(gradeId, num);
        }
        return Ret.ok().set("notice", hashMap).set("unCheckNum", map);
    }

    /**
     * 添加年级公告
     */
    public Ret addGradeNotice(Integer userId, Integer userType, String notice) throws Exception {
        
        if (userType != Const.UserType.admin) {
            return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
        }
        //查询当前用户是否在有发公告的权限
        List<OrgAdmin> list = OrgAdmin.dao.find("SELECT * FROM org_admin WHERE adminId = ? AND stratum = 2 ", userId);
        if (list.isEmpty()) {
            return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
        }
        for(OrgAdmin oa : list) {
        	Integer stratumId = oa.getStratumId();
        	if(stratumId == 1 || stratumId == 2 || stratumId == 5) {
        		Integer gradeId = stratumId;
        		GradeNotice notice1 = new GradeNotice();
                notice1.setUserId(userId);
                notice1.setGradeId(gradeId);
                notice1.setNotice(notice);
                notice1.save();
                //记录阅读状态
                //查询该年级用户
                List<Record> records = Db.find("SELECT stu.id FROM student stu INNER JOIN org_class oc ON oc.id = stu.clasId WHERE stu.isDele = 0 AND oc.adminGradeId = ?", gradeId);
                //查询当前年级的教师
                List<Record> recordList = Db.find("SELECT adminId FROM org_admin WHERE stratum  = 1 OR (stratum = 2 AND stratumId = ?)", gradeId);
                List<Record> records1 = Db.find("SELECT oa.adminId FROM org_admin oa INNER JOIN org_class oc ON oa.stratumId = oc.id WHERE oc.adminGradeId = ?", gradeId);
                recordList.addAll(records1);
                Set<Integer> adminId = recordList.stream().map(record -> record.getInt("adminId")).collect(Collectors.toSet());
                ArrayList<GradeNoticeLog> gradeNotices = new ArrayList<>(records.size());
                Set<Integer> id = records.stream().map(record -> record.getInt("id")).collect(Collectors.toSet());
                for (Integer integer : id) {
                    GradeNoticeLog gradeNotice = new GradeNoticeLog();
                    gradeNotice.setNoticeId(notice1.getId());
                    gradeNotice.setUserId(integer);
                    gradeNotice.setGradeId(gradeId);
                    gradeNotice.setUserType(2);
                    gradeNotices.add(gradeNotice);
                }
                for (Integer integer : adminId) {
                    GradeNoticeLog gradeNotice = new GradeNoticeLog();
                    gradeNotice.setNoticeId(notice1.getId());
                    gradeNotice.setUserId(integer);
                    gradeNotice.setGradeId(gradeId);
                    gradeNotice.setUserType(1);
                    gradeNotices.add(gradeNotice);
                }
                Db.batchSave(gradeNotices, gradeNotices.size());
        	}
        }
        return Ret.ok();
    }

    /**
     * 修改公告
     */
    public Ret updateGradeNotice(Integer userId, Integer userType, String notice, Integer noticeId) throws Exception {
        GradeNotice gradeNotice = GradeNotice.dao.findById(noticeId);
        if (BeanUtil.isEmpty(gradeNotice)) {
            return Ret.fail().set("error", EnumError.NOTICE_NOT_EXIST.getObj());
        }
        
        if (userType != Const.UserType.admin) {
            return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
        }
        //查询当前用户是否在有修改公告的权限
        List<OrgAdmin> list = OrgAdmin.dao.find("SELECT * FROM org_admin WHERE adminId = ? AND ((stratum = 1) OR (stratum = 2 AND stratumId = ?))", userId, gradeNotice.getGradeId());
        if (list.isEmpty()) {
            return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
        }
        gradeNotice.setNotice(notice);
        gradeNotice.setUserId(userId);
        gradeNotice.setUpdateTime(LocalDateTime.now());
        gradeNotice.update();
        return Ret.ok();
    }

    /**
     * 删除
     */
    @Before(Tx.class)
    public Ret delGradeNotice(Integer userId, Integer userType, Integer noticeId) throws Exception {
        GradeNotice gradeNotice = GradeNotice.dao.findById(noticeId);
        if (BeanUtil.isEmpty(gradeNotice)) {
            return Ret.fail().set("error", EnumError.NOTICE_NOT_EXIST.getObj());
        }
        
        if (userType != Const.UserType.admin) {
            return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
        }
        //查询当前用户是否在有删除公告的权限
        List<OrgAdmin> list = OrgAdmin.dao.find("SELECT * FROM org_admin WHERE adminId = ? AND ((stratum = 1) OR (stratum = 2 AND stratumId = ?))", userId, gradeNotice.getGradeId());
        if (list.isEmpty()) {
            return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
        }
        Db.delete("DELETE FROM grade_notice_log WHERE noticeId = ?", noticeId);
        gradeNotice.delete();
        return Ret.ok();
    }

    /**
     * 查看年级公告
     */
    public Ret lookOverGradeNotice(Integer noticeLogId) {
        Cache redis = Redis.use();
        GradeNoticeLog noticeLog = GradeNoticeLog.dao.findById(noticeLogId);
        if (BeanUtil.isEmpty(noticeLog)) {
            return Ret.fail().set("error", EnumError.NOTICE_LOG_NOT_EXIST.getObj());
        }
        noticeLog.setState(2);
        noticeLog.update();
        //查询已读未读
        List<GradeNoticeLog> gradeNoticeLogs = GradeNoticeLog.dao.find("SELECT id,state,userId,userType FROM grade_notice_log WHERE noticeId = ?", noticeLog.getNoticeId());
        gradeNoticeLogs.stream().forEach(gradeNoticeLog -> {
            if (gradeNoticeLog.getUserType() == 2) {
                Student o = redis.get(Const.user.Student + gradeNoticeLog.getUserId());
                gradeNoticeLog.put("pic", o.getAvatarUrl());
                gradeNoticeLog.put("name", o.getName());
                gradeNoticeLog.put("sex", o.getSex());
                gradeNoticeLog.put("accountId", o.getAccountId());
            } else {
                Admin o = redis.get(Const.user.Admin + gradeNoticeLog.getUserId());
                gradeNoticeLog.put("name", o.getName());
                gradeNoticeLog.put("pic", o.getAvatarUrl());
                gradeNoticeLog.put("accountId", o.getAccountId());
            }
        });
        List<GradeNoticeLog> list = gradeNoticeLogs.stream().filter(gradeNoticeLog -> gradeNoticeLog.getState() == 2).collect(Collectors.toList());
        List<GradeNoticeLog> collect = gradeNoticeLogs.stream().filter(gradeNoticeLog -> gradeNoticeLog.getState() == 1).collect(Collectors.toList());
        return Ret.ok().set("checkNum", list.size()).set("unCheckNum", collect.size()).set("checkList", list).set("uncheckList", collect);
    }
    
	
	
	
	
	
	
	
	
	
	
}
